<?php
/**
 * @package MicroPDO
 */
/**
 * @package MicroPDO
 * @author Lukasz Stosik <lstosik@gmail.com>
 * @license http://www.opensource.org/licenses/lgpl-3.0.html GNU Lesser General Public License
 */
class MicroPDO_PDO extends PDO {
    function __construct($dsn, $username = '', $password = '') {
	parent::__construct($dsn, $username, $password);
	$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
	/**
	 * @param string|object $sql
	 * @return PDOStatement
	 */
    protected function getStatement($sql) {
	return  $this->query(''.$sql);
    }

	/**
	 * @param string|object $sql
	 * @return PDOStatement
	 */
    protected function getPreparedStatement($sql) {
	static $statements = array();
	$sql = ''.$sql;
	if (isset($statements[$sql])) {
	    $statements[$sql]->closeCursor();
	    return $statements[$sql];
	}
	$stmt = $this->prepare($sql);
	if ($stmt) {
	    $statements[$sql] = $stmt;
	}
	return $stmt;
    }

	/**
	 * @param string|object $sql
	 * @param array $parameters
	 * @return PDOStatement
	 */
    protected function getExecutedStatement($sql, $parameters = array()) {
	if (is_array($parameters) && empty($parameters)) {
	    $stmt = $this->getStatement($sql);
	    $stmt->execute();
	} else {
	    if(!is_array($parameters)) {
		$parameters = array($parameters);
	    }
	    $stmt = $this->getPreparedStatement($sql);
	    $stmt->execute($parameters);
	}
	return $stmt;
    }

	/**
	 * @param String|SqlBuilder $sql
	 * @param array $parameters
	 * @return mixed|false wynik lub false w wypadku porazki
	 */
    function getOne($sql, $parameters = array()) {
	$stmt = $this->getExecutedStatement($sql, $parameters);
	$row = $stmt->fetch(PDO::FETCH_NUM);
	return $row[0];
    }

	/**
	 * Pobiera tylko jedna kolumne z wyniku zapytania.
	 * @param String|SqlBuilder $sql
	 * @param array $parameters
	 * @return array
	 */
    function getCol($sql, $parameters = array()) {
	$stmt = $this->getExecutedStatement($sql, $parameters);
	$rows = $stmt->fetchAll(PDO::FETCH_NUM);
	$result = array();
	foreach($rows as $row) {
	    $result[] = $row[0];
	}
	return $result;
    }


	/**
	 * @param string|SqlBuilder $sql
	 * @param array $parameters
	 * @return array
	 */
    function getAll($sql, $parameters = array()) {
	$stmt = $this->getExecutedStatement($sql, $parameters);
	return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

	/**
	 * @param string|SqlBuilder $sql
	 * @param array $parameters
	 * @return array
	 */
    function getRow($sql, $parameters = array()) {
	$stmt = $this->getExecutedStatement($sql, $parameters);
	return $stmt->fetch(PDO::FETCH_ASSOC);
    }

	/**
	 * @param string|SqlBuilder $sql
	 * @param array $parameters
	 * @return object
	 */
    function getObject($sql, $parameters = array()) {
	$stmt = $this->getExecutedStatement($sql, $parameters);
	return $stmt->fetch(PDO::FETCH_OBJ);
    }


    function getAssoc($sql, $parameters = array()) {
	$result =array();
	$res = $this->getAll($sql, $parameters);
	if (empty($res)) {
	    return $result;
	}
	reset($res);
	$colnum = count(current($res));
	foreach($res as $row) {
	    $keys = array_keys($row);
	    $key = $row[$keys[0]];
	    $result[$key] = $row;
	}
	return $result;
    }
	/**
	 * @param	string	$sql zapytane
	 * @return	array	tabela z opcjami
	 */
    function getDict($sql, $parameters = array()) {
	$result = array();
	$res = $this->getAll($sql, $parameters);
	if (empty($res)) {
	    return $result;
	}
	reset($res);
	$keys = array_keys(current(&$res));
	if (count($keys) < 2) {
	    throw new PDOException('Not enought fields to create a dictionary');
	}
	foreach($res as $row) {
	    $key = $row[$keys[0]];
	    $value = $row[$keys[1]];
	    $result[$key] = $value;
	}
	return $result;
    }

	/**
	 * @param string $tableName
	 * @return MicroPDO_Dataobject
	 */
    function factory($tableName) {
	require_once 'MicroPDO/DataObject.php';
	return new MicroPDO_DataObject($tableName, $this);
    }

	/**
	 * @param string|object $sql query
	 * @param mixed $parameters
	 * @return int number of affected rows
	 */
    function exec($sql, $parameters = array()) {
	if (empty($parameters)) {
	    return parent::exec(''.$sql);
	} else {
	    $stmt = $this->getExecutedStatement($sql, $parameters);
	    return $stmt->rowCount();
	}
    }
}



